package com.company.card_service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.company.card_service.mapper.*;
import com.company.card_service.model.*;
import com.company.card_service.service.EmployeeViewService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.company.card_service.util.DateUtil;
import com.company.card_service.vo.*;
import com.company.card_service.vo.respvo.ChatUserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 赵志浩
 * @since 2022-09-15 04:15:06
 */
@Service
@Slf4j
public class EmployeeViewServiceImpl extends ServiceImpl<EmployeeViewMapper, EmployeeView> implements EmployeeViewService {


    @Autowired
    private AddPhoneMapper addPhoneMapper;

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private EmployeeDownloadMapper employeeDownloadMapper;

    @Autowired ForwardViewMapper forwardViewMapper;

    @Autowired
    private UserLoginLogMapper userLoginLogMapper;

    @Override
    public EmployeeViewVo getEmployeeView(Long employeeId) {
        //构造返回值
        EmployeeViewVo employeeViewVo = new EmployeeViewVo();
        //构造三样数据，
        // 总访问量
        LambdaQueryWrapper<EmployeeView> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(EmployeeView::getEmployeeId,employeeId);
        Long aLong = this.baseMapper.selectCount(lambdaQueryWrapper);
        employeeViewVo.setAllView(aLong);
        //近七天访问量
        long l = System.currentTimeMillis() - 604800000;
        LambdaQueryWrapper<EmployeeView> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.le(EmployeeView::getCreateTime,new Date())
                .ge(EmployeeView::getCreateTime,new Date(l))
                .eq(EmployeeView::getEmployeeId,employeeId);
        Long aLong1 = this.baseMapper.selectCount(lambdaQueryWrapper1);
        employeeViewVo.setRecentView(aLong1);
        //今天的访问量
        //获取当天0点的毫秒数
        long zero =  System.currentTimeMillis()-
                ( System.currentTimeMillis()+ TimeZone.getDefault().getRawOffset()) % (1000 * 3600 * 24);
        LambdaQueryWrapper<EmployeeView> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper2.ge(EmployeeView::getCreateTime,new Date(zero))
                .le(EmployeeView::getCreateTime,new Date())
                .eq(EmployeeView::getEmployeeId,employeeId);
        Long aLong2 = this.baseMapper.selectCount(lambdaQueryWrapper2);
        employeeViewVo.setTodayView(aLong2);
        //返回封装的值
        return employeeViewVo;
    }
    @Override
    public ChartResVo getChartData(Long employeeId) {
        long l = System.currentTimeMillis() - 604800000;
        Date date = new Date();
        Date date1 = new Date(l);
        String startTime = DateUtil.formatDate(date1);
        String endTime = DateUtil.formatDate(date);
        List<ViewCountVo> chartData = this.baseMapper.getChartData(employeeId, startTime, endTime);
        //返回结果
        ChartResVo chartResVo = new ChartResVo();
        //x轴数据
        List<String> dateList = chartData.stream().map(ViewCountVo::getJoinTime).collect(Collectors.toList());
        //y轴数据
        List<Integer> countList = chartData.stream().map(ViewCountVo::getUserCount).collect(Collectors.toList());
        chartResVo.setCategories(dateList);
        YTittleAndData yTittleAndData = new YTittleAndData();
        yTittleAndData.setTittle("客户个数");
        yTittleAndData.setEmployeeData(countList);
        chartResVo.setYTittleAndData(yTittleAndData);
        return chartResVo;
    }
    @Override
    public List<historyEmployeeViewDataVo> getHistoryData(long employeeId,FormSearchTimeVo formSearchTimeVo) throws ParseException {
        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(formSearchTimeVo.getEndTime());
        long l = date.getTime() - 604800000;
        Date date1 = new Date(l);
        String startTime = DateUtil.formatDate(date1);
        String endTime = DateUtil.formatDate(date);
        //构造返回值
        List<historyEmployeeViewDataVo> historyList = new ArrayList<>();
        formSearchTimeVo.setStartTime(startTime);
        formSearchTimeVo.setEndTime(endTime);
        List<ViewCountVo> stopTime = new ArrayList<>();
        List<ViewCountVo> messageViewCountVo = messageMapper.findCount(employeeId,formSearchTimeVo.getStartTime(),formSearchTimeVo.getEndTime());
        List<ViewCountVo> downViewCountVo = employeeDownloadMapper.findCount(employeeId,formSearchTimeVo.getStartTime(),formSearchTimeVo.getEndTime());
        List<ViewCountVo> addPhoneViewCountVo=addPhoneMapper.findCount(employeeId,formSearchTimeVo.getStartTime(),formSearchTimeVo.getEndTime());
        List<ViewCountVo> chartData = this.baseMapper.getChartData(employeeId, formSearchTimeVo.getStartTime(), formSearchTimeVo.getEndTime());

        //计算累计和平均
        int messageCount = messageViewCountVo.stream().mapToInt(ViewCountVo::getUserCount).sum();
        int downloadCount = downViewCountVo.stream().mapToInt(ViewCountVo::getUserCount).sum();
        int addPhoneCount = addPhoneViewCountVo.stream().mapToInt(ViewCountVo::getUserCount).sum();
        int chartCount = chartData.stream().mapToInt(ViewCountVo::getUserCount).sum();

        //计算次停留时间
        //先找出哪些人访问过
        LambdaQueryWrapper<EmployeeView> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(EmployeeView::getEmployeeId,employeeId)
                .lt(EmployeeView::getCreateTime,date)
                .gt(EmployeeView::getCreateTime,date1);
        List<EmployeeView> employeeViews = this.baseMapper.selectList(lambdaQueryWrapper);
        //抽取出他们的id
        List<Integer> UserIdList = employeeViews.stream().map(EmployeeView::getUserId).distinct().collect(Collectors.toList());
        log.info(UserIdList.toString());
        //根据id找出他们的登录时间和登出时间
        AtomicLong onlineTime = new AtomicLong();
        UserIdList.stream().forEach(item->{
            log.info("我"+item);
            if(item != null){
                LambdaQueryWrapper<UserLoginLog> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                lambdaQueryWrapper1.eq(UserLoginLog::getUserId,item);
                List<UserLoginLog> userLoginLogs = userLoginLogMapper.selectList(lambdaQueryWrapper1);
                if(userLoginLogs != null){
                    log.info("你"+userLoginLogs.toString());
                    userLoginLogs.stream().forEach(userLoginLog->{
                        //登录时间
                        Date createTime = userLoginLog.getCreateTime();
                        //登出时间
                        Date logoutTime = userLoginLog.getLogoutTime();
                        //在线时间的毫秒数
                        if(createTime != null && logoutTime != null){
                            onlineTime.getAndAdd((logoutTime.getTime() - createTime.getTime()) / 60000);
                        }
                    });
                }
            }
        });
        //然后封装数据
        for (int i = 0; i < 9; i++) {
            historyEmployeeViewDataVo historyEmployeeViewDataVo = new historyEmployeeViewDataVo();
            if(i == 0){
                historyEmployeeViewDataVo.setTime("累计");
                historyEmployeeViewDataVo.setViewNum(chartCount);
                historyEmployeeViewDataVo.setAddNum(addPhoneCount);
                historyEmployeeViewDataVo.setLoadNum(downloadCount);
                historyEmployeeViewDataVo.setMessageNum(messageCount);
                historyEmployeeViewDataVo.setStopTime(Integer.valueOf(String.valueOf(onlineTime)));
                historyList.add(historyEmployeeViewDataVo);
            }
            else if(i == 1){
                historyEmployeeViewDataVo.setTime("平均");
                historyEmployeeViewDataVo.setViewNum(chartCount/7);
                historyEmployeeViewDataVo.setAddNum(addPhoneCount/7);
                historyEmployeeViewDataVo.setLoadNum(downloadCount/7);
                historyEmployeeViewDataVo.setMessageNum(messageCount/7);
                historyEmployeeViewDataVo.setStopTime(Integer.valueOf(String.valueOf(onlineTime))/7);
                historyList.add(historyEmployeeViewDataVo);
            }
            else if(i >= 2) {
                if(i-2<chartData.size()){
                    historyEmployeeViewDataVo.setTime(chartData.get(i-2).getJoinTime());
                    historyEmployeeViewDataVo.setViewNum(chartData.get(i-2).getUserCount());
                }
                if(i-2<addPhoneViewCountVo.size()){
                    historyEmployeeViewDataVo.setAddNum(addPhoneViewCountVo.get(i-2).getUserCount());
                }
                if(i-2<downViewCountVo.size()){
                    historyEmployeeViewDataVo.setLoadNum(downViewCountVo.get(i-2).getUserCount());
                }
                if(i-2<messageViewCountVo.size()){
                    historyEmployeeViewDataVo.setMessageNum(messageViewCountVo.get(i-2).getUserCount());
                }
                if(i-2<chartData.size()){
                    LambdaQueryWrapper<UserLoginLog> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper1.like(UserLoginLog::getCreateTime,chartData.get(i-2).getJoinTime());
                    List<UserLoginLog> userLoginLogs = userLoginLogMapper.selectList(lambdaQueryWrapper1);
                    AtomicLong onlineOneTime = new AtomicLong();
                    userLoginLogs.stream().forEach(item->{
                        //登录时间
                        Date createTime = item.getCreateTime();
                        //登出时间
                        Date logoutTime = item.getLogoutTime();
                        onlineOneTime.getAndAdd((logoutTime.getTime() - createTime.getTime()) / 60000);
                    });
                    historyEmployeeViewDataVo.setStopTime(Integer.valueOf(String.valueOf(onlineOneTime)));
                }
                historyList.add(historyEmployeeViewDataVo);
            }
        }
        return historyList;
    }

    @Override
    public Map<String, Object> getUserDay(Integer employeeId) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar instance = Calendar.getInstance();
        String format1 = format.format(instance.getTime()); //今天的时间
        instance.add(Calendar.DATE,-7);
        String format2 =  format.format(instance.getTime()); //一周前的时间

        Map<String, Object> map = new HashMap<>();

        LambdaQueryWrapper<EmployeeView> wrapper1 = new LambdaQueryWrapper<>();
        //客户总数
        wrapper1.eq(EmployeeView::getEmployeeId,2);
        List<EmployeeView> viewList = baseMapper.selectList(wrapper1);
        Set<Integer> collect1 = viewList.stream()
                .map(EmployeeView::getUserId)
                .collect(Collectors.toSet());
        map.put("userAllCount",collect1.size());

        LambdaQueryWrapper<EmployeeView> wrapper2 = new LambdaQueryWrapper<>();
        //近七日新增
        wrapper2.eq(EmployeeView::getEmployeeId,2);
        wrapper2.ge(EmployeeView::getCreateTime,format2);
        wrapper2.le(EmployeeView::getCreateTime,format1);
        List<EmployeeView> employeeViews = baseMapper.selectList(wrapper2);
        Set<Integer> collect2 = employeeViews.stream()
                .map(EmployeeView::getUserId).collect(Collectors.toSet());
        map.put("userSevenAdd",collect2.size());

        LambdaQueryWrapper<EmployeeView> wrapper3 = new LambdaQueryWrapper<>();
        //今日新增
        wrapper3.eq(EmployeeView::getEmployeeId,2);
        wrapper3.like(EmployeeView::getCreateTime,format1);
        List<EmployeeView> views = baseMapper.selectList(wrapper3);
        Set<Integer> collect = views.stream().map(EmployeeView::getUserId).collect(Collectors.toSet());
        map.put("userTodayAdd",collect.size());

        //近七天客户趋势
        List<ChatUserVo> userDayList = baseMapper.getUserDay(employeeId, format2, format1);
        List<String> xData = userDayList.stream().map(ChatUserVo::getJoinTime).collect(Collectors.toList());
        List<Integer> yData = userDayList.stream().map(ChatUserVo::getUserCount).collect(Collectors.toList());
        map.put("xData",xData);
        map.put("yData",yData);
        return map;
    }

    @Override
    public List<EmployeeAllUsers> selectAllUsers(Integer employeeId,Integer page,Integer limit) {
        Page<EmployeeAllUsers> pageParam = new Page<>(page,limit);
        List<EmployeeAllUsers> employeeAllUsers = baseMapper.selectAllUsers(pageParam,employeeId);
        employeeAllUsers.stream().forEach(item -> this.getCount(item,employeeId));
        return employeeAllUsers;
    }

    @Override
    public List<EmployeeAllUsers> queryAllUsersByPhone(Integer employeeId,String phone,Integer page,Integer limit) {
        Page<EmployeeAllUsers> pageParam = new Page<>(page,limit);
        List<EmployeeAllUsers> employeeAllUsers = baseMapper.queryAllUsersByPhone(pageParam,employeeId,phone);
        employeeAllUsers.stream().forEach(item -> this.getCount(item,employeeId));
//        employeeAllUsers.stream().forEach(item -> this.getNewCount(item,employeeId));
        return employeeAllUsers;
    }

    @Override
    public ChartResVo getChartDataByCompany(Integer companyId) {
        long l = System.currentTimeMillis() - 15552000000l;
        Date date = new Date();
        Date date1 = new Date(l);
        String startTime = DateUtil.formatDate(date1);
        String endTime = DateUtil.formatDate(date);
        List<ViewCountVo> chartData = this.baseMapper.getChartDataByCompany(Long.valueOf(companyId), startTime, endTime);
        //返回结果
        ChartResVo chartResVo = new ChartResVo();
        //x轴数据
        List<String> dateList = chartData.stream().map(ViewCountVo::getJoinTime).collect(Collectors.toList());
        //y轴数据
        List<Integer> countList = chartData.stream().map(ViewCountVo::getUserCount).collect(Collectors.toList());
        chartResVo.setCategories(dateList);
        YTittleAndData yTittleAndData = new YTittleAndData();
        yTittleAndData.setTittle("客户个数");
        yTittleAndData.setEmployeeData(countList);
        chartResVo.setYTittleAndData(yTittleAndData);
        return chartResVo;
    }

    private EmployeeAllUsers getNewCount(EmployeeAllUsers item,Integer employeeId) {
        Integer newCount = baseMapper.getNewCount(item.getId(), employeeId);
        item.setCount(newCount);
        return item;
    }

    private EmployeeAllUsers getCount(EmployeeAllUsers item,Integer employeeId) {
        LambdaQueryWrapper<EmployeeView> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(EmployeeView::getEmployeeId,employeeId);
        wrapper1.eq(EmployeeView::getUserId,item.getId());
        Long count1 = baseMapper.selectCount(wrapper1);

        LambdaQueryWrapper<AddPhone> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(AddPhone::getEmployeeId,employeeId);
        wrapper2.eq(AddPhone::getUserId,item.getId());
        Long count2 = addPhoneMapper.selectCount(wrapper2);

        LambdaQueryWrapper<ForwardView> wrapper3 = new LambdaQueryWrapper<>();
        wrapper3.eq(ForwardView::getEmployeeId,employeeId);
        wrapper3.eq(ForwardView::getUserId,item.getId());
        Long count3 = forwardViewMapper.selectCount(wrapper3);

        LambdaQueryWrapper<EmployeeDownload> wrapper4 = new LambdaQueryWrapper<>();
        wrapper4.eq(EmployeeDownload::getEmployeeId,employeeId);
        wrapper4.eq(EmployeeDownload::getUserId,item.getId());
        Long count4 = employeeDownloadMapper.selectCount(wrapper4);

        LambdaQueryWrapper<Message> wrapper5 = new LambdaQueryWrapper<>();
        wrapper5.eq(Message::getEmployeeId,employeeId);
        wrapper5.eq(Message::getUserId,item.getId());
        Long count5 = messageMapper.selectCount(wrapper5);

        item.setCount(Integer.parseInt(count1.toString())+Integer.parseInt(count2.toString())+Integer.parseInt(count3.toString())+Integer.parseInt(count4.toString())+Integer.parseInt(count5.toString()));
        return item;
    }

}
